import logging
import os
import re
import time
import datetime
import allure
import pytest
import uiautomator2 as u2
from time import sleep
from common.decs import relations


class App:
    def __init__(self):
        self.relations={}
        self.driver=u2.connect_usb()
        self.package=''
        #切换成fastInput输入法
        self.driver.set_fastinput_ime(True)

    def dev_connect(self):
        '''
        链接设备
        :param name:设备名称
        :return:
        '''
        self.driver=u2.connect_usb()
        return self.driver
    def appstart(self,package=''):
        '''
        打开app
        :param package:app的包名
        :return:
        '''
        #打开app
        try:
            self.driver.app_start(package)
            self.driver.implicitly_wait(10)
            self.package=package
            self.sleep(1)
        except Exception as e:
            self.close(package)
            self.driver.app_start(package)
            self.driver.implicitly_wait(10)
        return self.package

    def __find_ele(self,locator=""):
        '''
        自动判断元素定位方法
        :param locator: 元素定位
        :return:
        '''
        #如果元素以com开头，就用id定位
        if locator.startswith("com"):
            return self.driver(resourceId=locator)
        #如果元素以//开头，就用xpath定位
        elif locator.startswith("//"):
            return self.driver.xpath(locator)
        #否则用text定位
        else:
            return self.driver(textContains=locator)
    def click(self,locator1='',locator2=''):
        '''
        点击操作
        :param locator:
        :return:
        # '''
        # try:
        #如果第二个元素存在，就用坐标点击
        if locator2:
            self.driver.click(float(locator1),float(locator2))
        #否则就用element点击
        elif(locator1.startswith("(")):
            self.pxclick(locator1)
        else:
            ele=self.__find_ele(locator1)
            ele.click()
    def double_click(self,xy='',time=''):
        '''
        双击
        :param x:X坐标
        :param y:Y坐标
        :param time:双击时间间隔
        :return:
        '''
        if xy.startswith("("):
            sleep(1)
            cleaned_key = xy.strip("()")
            # 以逗号分割字符串
            parts = cleaned_key.split(",")
            # 将分割后的字符串转换为浮点数
            float_numbers = [float(part.strip()) for part in parts]
            print(float_numbers)
            x = float_numbers[0]
            y = float_numbers[1]
            self.driver.double_click(x, y,time)
        else:
            xy=xy.split(",")
            x=xy[0]
            y=xy[1]
            x=float(x)
            y=float(y)
            time=float(time)
            self.driver.double_click(x,y,time)

    def long_click(self,locator="",locator1=""):
        '''
        长按
        :param x:x坐标
        :param y: y坐标
        :param time: 长按时间
        :return:
        '''
        #如果第二个元素存在就按照坐标来长按
        if locator1:
            self.driver.long_click(float(locator),float(locator1),2)
        else:
            ele=self.__find_ele(locator)
            ele.long_click()

    def pxclick(self,key=""):
        sleep(0.5)
        cleaned_key = key.strip().strip("()")
        # 以逗号分割字符串
        parts = cleaned_key.split(",")
        # 将分割后的字符串转换为浮点数
        float_numbers = [float(part.strip()) for part in parts]
        print(float_numbers)
        x = float_numbers[0]
        y = float_numbers[1]
        self.driver.click(x,y)
    def swipedown(self):
        device_info = self.driver.info
        print(device_info)
        start_x = device_info['displayWidth'] // 2
        start_y = int(device_info['displayHeight'] * 0.8)
        end_x = device_info['displayWidth'] // 2
        end_y = int(device_info['displayHeight'] * 0.2)
        self.driver.drag(start_x, start_y, end_x, end_y)
    def Swipe(self,params=""):
        '''
        滑动
        :param params: 滑动方向 up down right left
        :return:
        '''
        self.driver.swipe_ext(params)
    def Drag(self,x1,x2,y1,y2):
        if y2:
            x1=float(x1)
            x2=float(x2)
            y1=float(y1)
            self.driver.drag(x1,y1,x2,y2,0.1)
        else:
            x1 = float(x1)
            x2 = float(x2)
            y1 = float(y1)
            self.driver.drag(x1, y1, x2, y1, 0.1)
        # self.driver.drag(x1,y1,x2,y1,0.1)

    def swipetoele(self,target_text=""):
        # 获取屏幕尺寸
        screen_height = self.driver.info.get('displayHeight')
        screen_width = self.driver.info.get('displayWidth')
        # 不断下滑直到找到目标元素
        while True:
            elements = self.driver(text=target_text)
            if elements.exists:
                break
            # 从屏幕中间开始下滑，滑动距离可以根据实际情况调整
            self.driver.swipe(screen_width * 0.5, screen_height * 0.8, screen_width * 0.5, screen_height * 0.2)
    @relations
    def input(self,locator='',value=''):
        '''
        输入
        :param locator:
        :param value:
        :return:
        '''
        if locator.startswith("("):
            self.pxclick(locator)
            self.driver.clear_text()
            self.driver.send_keys(value,clear=True)
        else:
            #获取焦点
            ele=self.__find_ele(locator)
            ele.click()
            # self.driver.xpath(locator).click()
            # self.click(locator)
            logging.info("输入："+value)
            #清除原来输入框内的的文本
            self.driver.clear_text()
            #重新输入文本
            self.driver.send_keys(str(value),clear=True)
            # ele=self.__find_ele(locator)
            # ele.send_keys(value)
            print("输入："+value)
    def search(self):
        self.driver.press("enter")
        sleep(0.5)
    @relations
    def get_text(self,locator='',reg=""):
        '''获取文本信息'''
        ele=self.__find_ele(locator)
        info=ele.info
        #如果这个元素包含text文本信息
        if info["text"]:
            text=info["text"]
            if reg:
                text = re.findall(r'\d{14}', text)[0]
                self.relations[reg] = text
            else:
                #把文本信息存起来
                self.relations["text"]=text
            print(self.relations)
        else:
            text='不存在text'
            self.relations["text"] = text
        return self.relations
    def get_kh(self):
        # 获取当前时间的天数
        day = datetime.datetime.now().day
        # 获取当前时间小时数
        hour = datetime.datetime.now().hour
        # 获取当前时间分钟数
        minute = datetime.datetime.now().minute
        # 获取当前时间秒数
        second = datetime.datetime.now().second
        l1 = [day, hour, minute, second]
        l2 = []
        for i in l1:
            if i < 10:
                i = "0" + str(i)
            else:
                i = str(i)
            l2.append(i)
        kh = "".join(l2)
        self.relations["kh"] = "YZ" + kh
        logging.info("款号：" + self.relations["kh"])
        return
    #自定义存储关联信息
    def save_params(self,key='',value=''):
        try:
            if key.startswith("reg"):
                if value.startswith("//")or value.startswith("com"):
                    ele = self.__find_ele(value)
                    info = ele.info
                    value = info["text"]
                    value=re.findall(r'\d{14}', value)[0]
                else:
                    value=value
            else:
                if value.startswith("//") or value.startswith("com"):
                    ele = self.__find_ele(value)
                    info = ele.info
                    value = info["text"]
                else:
                    value = value
            self.relations[key]=value
            print(self.relations)
        except Exception as e:
            self.attachshoot()
            self.restart()
            pytest.fail()
        return self.relations
    def sleep(self,num):
        '''等待'''
        if type(num)==int:
            sleep(num)
        else:
            sleep(float(num))
    def close(self,package=''):
        self.sleep(1)
        self.driver.app_stop(package)
    def back(self,num=""):
        if num:
            for i in range(int(num)):
                self.driver.press("back")
        self.driver.press("back")

    def restart(self):
        # self.attachshoot()
        self.close(self.package)
        self.appstart(self.package)
        self.sleep(1)

    @relations
    def assert_equal(self,exp_value='',locator=''):
        ele = self.__find_ele(locator)
        try:
            try:
                info = ele.info
                if len(info["text"])>0:
                    act_value=info["text"]
                    logging.info("预期文案："+exp_value)
                    logging.info("检查文案："+act_value)
                    # self.attachshoot()
                    # allure.attach(open(self.relations["picture_file"], 'rb').read(), 'Screenshot',
                    #               attachment_type=allure.attachment_type.PNG)
                else:
                    act_value="不存在元素"
                    logging.info("预期文案：" + exp_value)
                    logging.info("检查文案：" + act_value)
            except Exception as e:
                act_value = "不存在元素"
                logging.info("预期文案：" + exp_value)
                logging.info("检查文案：" + act_value)

            if act_value.__contains__(exp_value) or exp_value.__contains__(act_value):
                pass
            else:
                self.attachshoot()
                self.restart()
                pytest.fail()
        except Exception as e:
            self.attachshoot()
            self.restart()
            pytest.fail()
    def attachshoot(self):
        time_stamp = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
        picture_file ='./ErrorImg/error{0}.png'.format(time_stamp)
        self.relations["picture_file"]=picture_file
        print(self.relations['picture_file'])
        self.driver.screenshot(picture_file)
        allure.attach(open(self.relations["picture_file"], 'rb').read(), 'Fail Screenshot',
                      attachment_type=allure.attachment_type.PNG)
        return picture_file

if __name__ == '__main__':
    # os.system('rd /s/q ErrorImg')
    # sleep(5)
    # os.mkdir("ErrorImg")
    app=App()
    app.dev_connect()
    # app.attachshoot()

    # app.dev_connect()
    app.appstart('com.yizhe.yizhe')
    app.swipedown()
    # app.sleep(2)
    # app.input('//*[@resource-id="app"]/android.view.View[2]',"15912341234")
    # app.sleep("1")
    # app.input('//*[@resource-id="app"]/android.view.View[3]',"341234")
    # app.click('//*[@resource-id="app"]/android.view.View[5]')
    # app.sleep("1")
    # app.click('//*[@text="登录"]')
    # s = 0
    # N=0
    # while True:
    #     a = datetime.now()
    #     #app.click('0.497', '0.418')
    #     app.double_click("0.497,0.418",0)
    #     b = datetime.now()
    #     s+=800
    #     N+=1
    #     print("运行时间："+str(b-a)+" 秒")
    #     print("金额：",s)
    #     print("点击次数",N)
    # app.sleep(3)
    # app.click('//*[@text="菜单"]')
    # app.click('//*[@resource-id="com.vivo.browser:id/menu_page_one"]/android.widget.RelativeLayout[2]')
    # app.click('//*[@text="金币大富翁"]')
    # app.sleep(1)
    # app.input('//*[@resource-id="app"]/android.view.View[3]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[3]',"dy54255723")
    # app.input('//*[@resource-id="app"]/android.view.View[3]/android.view.View[1]/android.view.View[1]/android.view.View[1]/android.view.View[4]','6371e2890f5a5')
    # app.click('//*[@text="进入游戏"]')
    # app.sleep(10)
    # app.click("0.144", "0.919")
    # app.click('0.469', '0.821')
    # app.save_params("账号",'13631258769')
    # app.click('//*[@text="主站"]')
    # app.sleep(1)
    # app.click('com.yishouapp.fumi:id/tv_one_key_login')
    # app.sleep(1)
    # app.click('密码登录')
    # app.sleep(1)
    # app.input('输入手机号码','{账号}')
    # app.input('输入密码','a11111')
    # app.click("com.yishouapp.fumi:id/cb_user_privacy")
    # app.click("确定")
    # app.sleep(2)
    # app.attachshoot()
    # try:
    #     app.click('//*[@resource-id="com.yishouapp.fumi:id/main_tab5"]/android.widget.ImageView[1]')
    # except Exception as e:
    #     app.driver.screenshot("error.png")
    # app.sleep(2)
    # time_stamp = time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(time.time()))
    # picture_file = os.path.join(os.getcwd(), '../lib/error/error{0}.png'.format(time_stamp))
    # app.attachshoot(picture_file)
